﻿package kliment.geom.color {
	import kliment.math.Calc;
	
	/**
	* ...
	* @author Kliment
	*/
	public class LABColor  extends ColorAbstract {
		private const WHITE:int = 255;
		private const WHITE_HALF:int = 128;
		
		public var rawL:Number = 0;
		public var rawA:Number = 0;
		public var rawB:Number = 0;
		
		public function LABColor(host:Color = null) {
			super(host);
		}
		
		public function get l():Number { return rawL * 100 }
		public function get a():Number { return rawA * WHITE - WHITE_HALF }
		public function get b():Number { return rawB * WHITE - WHITE_HALF }
		
		public function setValue(l:Number, a:Number, b:Number, update:Boolean = true):void {
			setRawValue(l / 100, (a + WHITE_HALF) / WHITE, (b + WHITE_HALF) / WHITE, update);
		}
		
		public function setRawValue(l:Number, a:Number, b:Number, update:Boolean = true):void {
			if (rawL == l && rawA == a && rawB == b) 
				return;
				
			rawL = Calc.inInterval(MIN_RAW, MAX_RAW, l);
			rawA = Calc.inInterval(MIN_RAW, MAX_RAW, a);
			rawB = Calc.inInterval(MIN_RAW, MAX_RAW, b);
			
			if (color && update) 
				color.valueChanged(Color.LAB);
		}
        
        public function toString():String {
			return "[LABColor l=" + l + " a=" + a + " b=" + b + "]";
		}
		
		public function clone():LABColor {
			var result:LABColor = new LABColor();
			result.setRawValue(rawL, rawA, rawB, false);
			return result;
		}
		
		public function toXYZColor(cmyk:XYZColor = null):XYZColor { return converToXYZ(this, cmyk) }
		static public function converToXYZ(lab:LABColor, xyz:XYZColor = null):XYZColor {
			if (!xyz) xyz = new XYZColor();
			var l:Number = (lab.rawL * 100 + 16) / 116;
			var a:Number = l + (lab.rawA * 255 - 128) / 500;
			var b:Number = l - (lab.rawB * 255 - 128) / 200;
			var x:Number = (a > .2069)?(a * a * a):(.1284 * (a - .1379));
			var y:Number = (l > .2069)?(l * l * l):(.1284 * (l - .1379));
			var z:Number = (b > .2069)?(b * b * b):(.1284 * (b - .1379));
			
			xyz.setRawValue(x, y, z, false)
			return xyz;
		}
	}
}